package com.yfbao.horizon.demo;

import cn.hutool.core.date.DateUtil;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.yfbao.horizon.utils.*;

import java.util.*;
import java.util.concurrent.*;
import java.util.regex.Pattern;

public class MutilMethodTest {
    private  static ExecutorService executorService = Executors.newFixedThreadPool(5);
    private  static ExecutorService executorService2 = Executors.newFixedThreadPool(10);


    private static final Cache<String, String> CACHE_MAP = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).maximumSize(200).build();;

    private static void doRandom(){
        for(int i=0;i<100;i++){
//            System.out.println(HorizonUtils.getIntRandom(100));
            System.out.println(HorizonUtils.getLongRandom());
        }
    }

    private static void testString(){
        String aaa ="test:-1:organization:2.7.1-TEST-SNAPSHOT:OrgOutsidePermission::-1730833917365171641:0:4s:97160:94";
        Long ten = -1730833917365171641L;
        long l = System.currentTimeMillis();
        aaa =aaa+":"+l;
        int index = aaa.lastIndexOf(":");
        System.out.println(aaa.contains(":"+ten+":"));
        System.out.println(aaa.substring(0,index));
        System.out.println(aaa.substring(index+1));
        System.out.println(l);
    }

    public static void main(String[] args) {
//        testString();
//        Random random = new Random();
//        long aLong = random.nextLong();
//        System.out.println(aLong);
//        doRandom();
//        testMutilCache();
//        testUUid();
//        mutilDo();
//        boolean b = checkPasswordStrengthForCustom("Zp123456789.", 9, true, true, true);
//        System.out.println("aaaa:"+b);
//        testTime();
        clearTask();
    }



    private static void clearTask(){
        List<String> list = new ArrayList<>();
        list.add("test1");
        list.add("test2");
        list.add("test3");
        list.add("test4");
        list.add("test5");
        for(int i=0;i<100;i++){
            int num = i % 5;
            String value = list.get(num);
            Random random =new Random();
            executorService2.submit(()->{
                try {
                    Thread.sleep(random.nextInt(100)+50);
                } catch (InterruptedException e) {
                    System.out.println("seleep error"+e);
                }
                System.out.println("ready task:"+value);
                mutiTest(value);
            });
        }
        System.out.println("all put inQueue");
    }

    private static final Object obj =new Object();
    private static LinkedBlockingQueue<String> clearTaskQueue = new LinkedBlockingQueue<>();
    private static void mutiTest(String clearKey){
        synchronized (obj) {
            if (clearTaskQueue.size() > 3) {
                System.out.println("clearCacheByEntityParams queue size:" + clearTaskQueue.size());
                Iterator<String> iterator = clearTaskQueue.iterator();
                while (iterator.hasNext()){
                    String next = iterator.next();
                    if (next.equals(clearKey)) {
                        System.out.println("clearCacheByEntityParams queue exist:"+clearKey);
                        return ;
                    }
                }
                clearTaskQueue.add(clearKey);
                if (clearTaskQueue.size() > 5) {
                    return ;
                }
            } else {
                clearTaskQueue.add(clearKey);
            }
        }

        executorService.submit(()->{
            String name = Thread.currentThread().getName()+"_"+System.currentTimeMillis();
            while (true){
                String data = null;
                try {
                    data = clearTaskQueue.poll(50, TimeUnit.MILLISECONDS);
                } catch (InterruptedException e) {
                    System.out.println(name+": get PermissionCacheClearQueue error，"+e);
                    break;
                }
                if(data ==null){
                    System.out.println(name+":get PermissionCacheClearQueue null");
                    break;
                }
                System.out.println(name+": do same .......");
                Random random =new Random();
                try {
                    Thread.sleep(random.nextInt(150)+50);
                } catch (InterruptedException e) {
                    System.out.println(name+":sleep error"+e);
                }
            }
            System.out.println("release thread...");
        });
    }

    public static boolean checkPasswordStrengthForCustom(String password, Integer minLen,Boolean numberEnable,Boolean specialEnable,Boolean upperAndLowerEnable){
        if(password.length()<minLen || password.length()>50){
            return false;
        }
        if(upperAndLowerEnable){
            if(!Pattern.matches(".*[a-z].*",password) || !Pattern.matches(".*[A-Z].*",password)){
                return false;
            }
        }
        if(numberEnable){
            if(!Pattern.matches(".*\\d.*",password)){
                return false;
            }
        }
        if(specialEnable){
            if(!Pattern.matches(".*[~`!@#$%^&*()_+-=\\[\\]{}|\\\\;:'\",.<>?/].*",password)){
                return false;
            }
        }
        return true;
    }


    public static void testTime(){
        for(int i =-0;i<20;i++){
            try {
                Thread.sleep(3333);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long time = DateUtil.beginOfMinute(new Date()).getTime();
            System.out.println(time);
        }
    }


    public static void mutilDo(){
        ExecutorService executorService = Executors.newFixedThreadPool(40);
        long start= System.currentTimeMillis();
        CountDownLatch countDownLatch = new CountDownLatch(100);
        for(int i=0;i<100;i++) {
            int finalI = i;
            executorService.execute(()->{
                System.out.println("thread num:"+ finalI);
                doTest();
                countDownLatch.countDown();
                System.out.println("thread num:"+ finalI+" countDown");
            });
        }
        long count = countDownLatch.getCount();
        try {
            Thread.sleep(2*1000);
//            countDownLatch.wait(10*1000);
            count = countDownLatch.getCount();
        } catch (InterruptedException e) {
//            e.printStackTrace();
        }
        System.out.println("total cost:"+(System.currentTimeMillis()-start)+" , count:"+count);
    }

    private static String doTest(){
        String cacheKey = "aaaa";
        String s = CACHE_MAP.getIfPresent(cacheKey);
        if(s !=null){
            System.out.println("获取缓存成功1");
            return s;
        }
        boolean tryProduceLock = ConcurrentUtils.tryLock(cacheKey);
        if(!tryProduceLock){
            System.out.println("get lock failed,wait....");
            ConcurrentUtils.spinWait(cacheKey,10*1000);
        }
        s = CACHE_MAP.getIfPresent(cacheKey);
        if(s ==null){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("select from db.................");
            CACHE_MAP.put(cacheKey,"asdadas");
        }
        if(tryProduceLock){
            ConcurrentUtils.releaseLockAndNotifyAll(cacheKey);
            System.out.println("释放锁成功");
        }
        System.out.println("获取缓存成功2");
        return s;
    }






    public static void testUUid(){
        for(int i=0;i<10;i++){
            System.out.println(ComUtils.uuidString());
        }
    }

    public static void testMutilCache(){
        String cacheName = "test";
        String cacheKey = "aaa";
        String cacheValue ="dasdasdasdasdasdasdasd";
        CacheUtil.putShortTimeCache(cacheName,cacheKey,cacheValue,8L);

        Object shortTimeCache = CacheUtil.getShortTimeCache(cacheName, cacheKey);
        if(shortTimeCache!=null){
            System.out.println(shortTimeCache);
            return;
        }
        System.out.println("null");

        try {
            Thread.sleep(8500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
